package raft.ThreadUtil;

import java.util.concurrent.*;

public class RaftThreadPool {

    ///获取计算机的支持的核心数
    private static int coreCpu = Runtime.getRuntime().availableProcessors();
    private static int maxPoolSize = coreCpu*2;
    private static final int queueSize = 1024;
    private static final long keepTime = 1000*60;
    private static TimeUnit keepTimeUnit = TimeUnit.MILLISECONDS;

    private static ThreadPoolExecutor threadPool = getThreadPool();
    private static ScheduledExecutorService scheduledPool = getScheduled();

    //得到线程池
    private static ThreadPoolExecutor getThreadPool(){
        return new RaftThreadPoolExecutor(coreCpu,maxPoolSize,keepTime,keepTimeUnit,new LinkedBlockingQueue<>(queueSize),new NameThreadFactory());
    }

    //得到延时执行池
    private static ScheduledExecutorService getScheduled(){
        return new ScheduledThreadPoolExecutor(coreCpu,new NameThreadFactory());
    }


    public static void scheduleAtFixedRate(Runnable r, long initDelay ,long delay){
        scheduledPool.scheduleAtFixedRate(r,initDelay,delay,TimeUnit.MILLISECONDS);
    }

    public static void scheduleWithFixedDelay(Runnable r,long delay){
        scheduledPool.scheduleAtFixedRate(r,0,delay,TimeUnit.MILLISECONDS);
    }

    //Callable 有返回值和抛出异常          Submit有返回值 接收异常 可以接收callable
    public static  <T> Future<T> submit(Callable r){ return threadPool.submit(r);}

    public static void execute(Runnable r ){ threadPool.execute(r);}

    public static void execute(Runnable r, boolean sync) {
        if (sync) {
            r.run();
        } else {
            threadPool.execute(r);
        }
    }



    //重新设置工厂 产出的线程为守护线程
    static class NameThreadFactory implements ThreadFactory{

        @Override
        public Thread newThread(Runnable r) {

            Thread t = new Thread(r);
            //设置为守护线程 主线程结束时结束
            //避免子线程如果为用户线程，子线程如果陷入死循环 ，主线程会等待子线程而不结束程序    孤儿进程
            //应用  网络连接的心跳监测   JVM垃圾回收

            //僵尸进程  进程创建子进程  子进程先结束，而父进程没有调用wait或waitpid获取子进程的状态信息，那么子进程的进程描述符仍然保存在系统中。
            t.setDaemon(true);
            //设置权重
            t.setPriority(5);

            return t;
        }
    }


}
